package se.webbzon.boltzmann.editor.component.sequence.panel;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.util.Collection;

import javax.swing.AbstractAction;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import se.webbzon.boltzmann.game.sequence.builder.dialogue.ChoiceDialogueRow;

public class ChoiceDialogueRowPanel extends AbstractDialogueRowPanel {
	
	// Auto generated serial version UID
	private static final long serialVersionUID = -3047866673431571573L;

	// The text fields of this panel
	private final JTextField choiceInput;
	
	// The lists of this panel
	private final JList<String> choices;
	
	/*============================================================
	Constructors
	============================================================*/

	public ChoiceDialogueRowPanel(ChoiceDialogueRow row) {
		super(row);
		
		// Create choice panel
		JPanel choicePanel = new JPanel();
		choicePanel.setLayout(new BorderLayout());
		choicePanel.add(new JLabel("Choices:"),BorderLayout.NORTH);
		
		// Crate choice list
		JPanel choiceListPanel = new JPanel();
		choiceListPanel.setLayout(new BorderLayout());
		
		DefaultListModel<String> choiceModel = 
				new DefaultListModel<String>();
		for (int i = 0; i < row.choices(); i++)
			choiceModel.addElement(row.getChoice(i));
		choices = new JList<String>(choiceModel);
		choices.addListSelectionListener(new ListSelectionListenerImpl());
		JScrollPane choiceScrollPane = new JScrollPane(choices);
		choiceScrollPane.setPreferredSize(new Dimension(-1,48));
		choiceListPanel.add(choiceScrollPane,BorderLayout.CENTER);
		
		JPanel choiceButtonPanel = new JPanel();
		choiceButtonPanel.setLayout(new BorderLayout());
		choiceButtonPanel.add(new JButton(new AddAction()),BorderLayout.WEST);
		choiceButtonPanel.add(new JButton(new RemoveAction()),BorderLayout.EAST);
		choiceListPanel.add(choiceButtonPanel,BorderLayout.SOUTH);
		
		choicePanel.add(choiceListPanel,BorderLayout.WEST);
		
		// Add glue
		choicePanel.add(Box.createHorizontalStrut(32),BorderLayout.CENTER);
		
		// Create choice input
		JPanel choiceConfigPanel = new JPanel();
		choiceConfigPanel.setLayout(new BorderLayout());
		
		JPanel choiceApplyPanel = new JPanel();
		choiceApplyPanel.setLayout(new BoxLayout(choiceApplyPanel,BoxLayout.X_AXIS));
		choiceInput = new JTextField();
		choiceInput.setPreferredSize(new Dimension(256,-1));
		choiceApplyPanel.add(new JLabel("Choice: "));
		choiceApplyPanel.add(choiceInput);
		choiceApplyPanel.add(new JButton(new ApplyTextAction()));
		choiceConfigPanel.add(choiceApplyPanel,BorderLayout.NORTH);
		
		choicePanel.add(choiceConfigPanel,BorderLayout.EAST);
		addPanel(choicePanel);
	}

	/*============================================================
	Public Methods
	============================================================*/
	
	@Override public boolean apply(Collection<String> errorMessages) {
		if (super.apply(errorMessages)) {
			
			// Update dialogue row
			ChoiceDialogueRow row = (ChoiceDialogueRow) getSequenceRow();
			row.clearChoices();
			for (int i = 0; i < choices.getModel().getSize(); i++)
				row.addChoice(choices.getModel().getElementAt(i));
			
			return true;
		} else
			return false;
	}
	
	/*============================================================
	Private Classes
	============================================================*/
	
	/** An abstract action used for the add choice button. **/
	private final class AddAction extends AbstractAction {
		
		// Auto generated serial version UID
		private static final long serialVersionUID = -71307749321357299L;
		
		/*============================================================
		Constructor
		============================================================*/

		public AddAction() {
			putValue(AbstractAction.NAME,"Add");
		}

		/*============================================================
		Public Methods
		============================================================*/
		
		@Override public void actionPerformed(ActionEvent event) {
			DefaultListModel<String> choiceModel = 
					(DefaultListModel<String>) choices.getModel();
			String choice = new String("Undefined");
			choiceModel.addElement(choice);
			choices.setSelectedValue(choice,true);
		}
		
	}
	
	/** An abstract action used for the remove choice button. **/
	private final class RemoveAction extends AbstractAction {
		
		// Auto generated serial version UID
		private static final long serialVersionUID = -49281153197571255L;
		
		/*============================================================
		Constructor
		============================================================*/

		public RemoveAction() {
			putValue(AbstractAction.NAME,"Remove");
		}

		/*============================================================
		Public Methods
		============================================================*/
		
		@Override public void actionPerformed(ActionEvent event) {
			
			DefaultListModel<String> choiceModel = 
					(DefaultListModel<String>) choices.getModel();
			int index = choices.getSelectedIndex();
			if (index >= 0)
				choiceModel.remove(index);
		}
		
	}
	
	/** An abstract action used for the apply text button. **/
	private final class ApplyTextAction extends AbstractAction {
		
		// Auto generated serial version UID
		private static final long serialVersionUID = -4108677692862553208L;
		
		/*============================================================
		Constructor
		============================================================*/

		public ApplyTextAction() {
			putValue(AbstractAction.NAME,"Apply Text");
		}

		/*============================================================
		Public Methods
		============================================================*/
		
		@Override public void actionPerformed(ActionEvent event) {
			int index = choices.getSelectedIndex();
			if (index >= 0) {
				DefaultListModel<String> choiceModel = 
						(DefaultListModel<String>) choices.getModel();
				String choice = choiceInput.getText();
				choiceModel.set(index,choice);
			}
		}
		
	}
	
	/** An implementation of a list selection listener. **/
	private final class ListSelectionListenerImpl implements ListSelectionListener {

		@Override public void valueChanged(ListSelectionEvent event) {
			int index = choices.getSelectedIndex();
			if (index >= 0)
				choiceInput.setText(choices.getModel().getElementAt(index));
		}
		
	}
	

}
